package edu.washington.cs.workflow.analysis.guistructure.uievents;

import org.uispec4j.Button;
import org.uispec4j.Panel;
import org.uispec4j.Trigger;
import org.uispec4j.UIComponent;
import org.uispec4j.Window;

import edu.washington.cs.workflow.analysis.guistructure.Spec4JUtils;
import edu.washington.cs.workflow.analysis.guistructure.UIActionTracer;
import edu.washington.cs.workflow.analysis.guistructure.uievents.UIEvent.WINDOW;
import edu.washington.cs.workflow.util.Utils;

public class ButtonEvent extends AbstractUIEvent {
	
	public final Button button;
	public final UIAction action;
	
	ButtonEvent(Button button, Panel panel, UIAction action) {
		Utils.checkNotNull(button);
		Utils.checkNotNull(action);
		Utils.checkNotNull(panel);
		Utils.checkTrue(action.equals(UIAction.Click), "Invalid: " + action);
		this.button = button;
		this.setCurrentPanel(panel);
		this.action = action;
	}

	@Override
	public UIComponent getUIComponent() {
		return this.button;
	}

	@Override
	public UIAction getAction() {
		return this.action;
	}
	
	@Override
	protected WINDOW probeWindowInfoInternal() {
		Trigger t = this.getTrigger();
//		Utils.debugPrintln("probe window in button: " + this.button.getAwtComponent().getToolTipText());
		WINDOW w = Spec4JUtils.getTriggeredDialog(this.button, t);
		Utils.checkNotNull(w);
		return w;
	}
	
	@Override
	public boolean canFireEvent() {
		return this.button.isEnabled().isTrue();
	}
	
	protected Trigger getTrigger() {
		return this.button.triggerClick();
	}

	@Override
	protected UIEventOutcome fireEventInternal() {
//		Utils.checkTrue(this.getCurrentPanel().isVisible().isTrue(), "The current panel must be visible.");
		
		//see does it pop up a Window?
		//XXX such strategy must be fixed, since double clicking
		//a button could have some side effects. For example,
		//in the calculator example,double chekcing a digital
		//will make it display twice on the screen. also, double
		//clicking the "=" sign will make it perform the computation
		//twice.
//		Trigger t = this.getTrigger();
//		Utils.debugprintln(" +++ " + UIActionTracer.tracer.getAllUIEntities().size());
		WINDOW winStatus = null;
		if(super.getWindowFlag() == null) {
			winStatus = super.probeWindowInfo();
		} else {
			winStatus = super.getWindowFlag();
		}		    
		Utils.checkNotNull(winStatus);
		
		UIEventOutcome outcome = new UIEventOutcome();
		Throwable error = null;
		
		//if there will be a window we do not click any more
		if(!winStatus.equals(WINDOW.NONE)) {
			outcome.setWindowStatus(winStatus);
			outcome.setTrigger(this.getTrigger());
			return outcome;
		}
		//if there is no window, do the click
		try {
		   this.button.click();
		} catch (Throwable e) {
//			e.printStackTrace();
//			System.exit(1);
			error = e;
		}
		
		if(error != null) {
		    outcome.setError(error);
		}
		outcome.setWindowStatus(winStatus);
		outcome.currentPanelClosed(super.isCurrentPanelClosed());
		
		return outcome;
	}
	
	@Override
	public String toString() {
		String title = "";
		if(this.getCurrentPanel() instanceof Window) {
			title = ((Window)this.getCurrentPanel()).getTitle();
		}
		return "Click button: " + this.button.getLabel() + ", at panel: "
		 + this.getCurrentPanel().getLabel()
//		 + ",  " + this.getCurrentPanel()
		 + ", title: " + title
		 + ", tooltip: " + this.button.getAwtComponent().getToolTipText()
		 + ", image: " + this.button.getAwtComponent().getIcon();
	}
}
